<?php
/**
 * 钱包实体
 */

namespace App\Commons\Domain\Module\Financial\Entity;

use App\Commons\Domain\Core\DomainEntity;
use App\Commons\Domain\Module\Financial\Model\Wallet;

class WalletEntity extends DomainEntity
{
    public const ENTITY = Wallet::class;

    /**
     * 创建钱包
     * @param string $uid 用户uid
     * @param int $coin_id 币种id
     */
    public function create(string $uid, int $coin_id)
    {
        # TODO:创建钱包
    }

    /**
     * 冻结钱包金额
     * @param int $wallet_id
     * @param float $amount
     * @return mixed
     */
    public function freeze(int $wallet_id, float $amount)
    {
        $wallet = $this->whereId($wallet_id)->lockForUpdate()->firstOrFail();

        throw_on($amount > $wallet->balance, 0xf00162);

        $wallet->balance = $wallet->balance - $amount;
        $wallet->frozen_balance = $wallet->frozen_balance + $amount;
        return $wallet->save();
    }

    /**
     * 释放冻结金额
     * @param int $wallet_id
     * @param float $amount
     * @return mixed
     */
    public function freedFreeze(int $wallet_id, float $amount)
    {
        $wallet = $this->whereId($wallet_id)->lockForUpdate()->firstOrFail();

        $wallet->balance = $wallet->balance + $amount;
        $wallet->frozen_balance = $wallet->frozen_balance - $amount;
        return $wallet->save();
    }

    /**
     * 单纯的减少账户的冻结金额
     * @param int $wallet_id
     * @param float $amount
     * @return mixed
     */
    public function cutFreeze(int $wallet_id, float $amount)
    {
        $wallet = $this->whereId($wallet_id)->lockForUpdate()->firstOrFail();

        throw_on($amount > $wallet->freeze, 0xf00462);

        $wallet->frozen_balance = $wallet->frozen_balance - $amount;

        return $wallet->save();
    }

    /**
     * 改变钱包锁定状态
     * @param int $wallet_id
     * @return mixed
     */
    public function changeLockStatus(int $wallet_id)
    {
        $wallet = $this->whereId($wallet_id)->firstOrFail();
        $locked_at = $wallet->locked_at ? null : now();
        return $wallet->update(compact('locked_at'));
    }

    /**
     * 增加充值待释放
     * @param int $wallet_id
     * @param float $amount
     * @return mixed
     */
    public function addReleased(int $wallet_id, float $amount)
    {
        $wallet = $this->whereId($wallet_id)->lockForUpdate()->firstOrFail();
        $wallet->to_released = $wallet->to_released + $amount;
        return $wallet->save();
    }

    /**
     * 释放充值金额
     * @param int $wallet_id
     * @param float $amount
     * @return mixed
     */
    public function release(int $wallet_id, float $amount)
    {
        $wallet = $this->whereId($wallet_id)->lockForUpdate()->firstOrFail();
        throw_on($amount > $wallet->to_released, 0xf00281);

        $wallet->balance = $wallet->balance + $amount;
        $wallet->to_released = $wallet->to_released - $amount;
        return $wallet->save();
    }

}
